{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57112e5c-7b0f-4ba7-9022-ae21e8ac0f42",
   "metadata": {},
   "outputs": [],
   "source": [
    "# imports\n",
    "\n",
    "import requests\n",
    "from bs4 import BeautifulSoup\n",
    "from IPython.display import Markdown, display"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b71a051-fc0e-46a9-8b1b-b58f685e800d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Constants\n",
    "OLLAMA_API = \"http://localhost:11434/api/chat\"\n",
    "HEADERS = {\"Content-Type\": \"application/json\"}\n",
    "MODEL = \"deepseek-r1:14b\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ed3be9dc-d459-46ac-a8eb-f9b932c4302f",
   "metadata": {},
   "outputs": [],
   "source": [
    "headers = {\n",
    "    \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36\"\n",
    "}\n",
    "\n",
    "class Website:\n",
    "    def __init__(self, url):\n",
    "        self.url = url\n",
    "        try:\n",
    "            response = requests.get(url, headers=headers, timeout=10)\n",
    "            response.raise_for_status()\n",
    "            soup = BeautifulSoup(response.content, 'html.parser')\n",
    "            self.title = soup.title.string if soup.title else \"No title found\"\n",
    "            if soup.body:\n",
    "                for irrelevant in soup.body([\"script\", \"style\", \"img\", \"input\"]):\n",
    "                    irrelevant.decompose()\n",
    "                self.text = soup.body.get_text(separator=\"\\n\", strip=True)\n",
    "            else:\n",
    "                self.text = \"No body content found\"\n",
    "        except requests.RequestException as e:\n",
    "            print(f\"Error fetching website: {e}\")\n",
    "            self.title = \"Error loading page\"\n",
    "            self.text = \"Could not load page content\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17ea76f8-38d9-40b9-8aba-eb957d690a0d",
   "metadata": {},
   "source": [
    "## Without Ollama package"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a6fd698-8e59-4cd7-bb53-b9375e50f899",
   "metadata": {},
   "outputs": [],
   "source": [
    "def house_renting(system_prompt, user_prompt):\n",
    "    messages = [\n",
    "        {\"role\": \"system\", \"content\": system_prompt},\n",
    "        {\"role\": \"user\", \"content\": user_prompt}\n",
    "    ]\n",
    "    payload = {\n",
    "        \"model\": MODEL,\n",
    "        \"messages\": messages,\n",
    "        \"stream\": False\n",
    "    }\n",
    "    response = requests.post(OLLAMA_API, json=payload, headers=HEADERS)\n",
    "    return response.json()['message']['content']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c826a52c-d1d3-493a-8b7c-6e75b848b453",
   "metadata": {},
   "source": [
    "## Introducing Ollama package "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "519e27da-eeff-4c1b-a8c6-e680fdf01da2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import ollama\n",
    "\n",
    "def house_renting_ollama(system_prompt, user_prompt):\n",
    "    try:\n",
    "        messages = [\n",
    "            {\"role\": \"system\", \"content\": system_prompt},\n",
    "            {\"role\": \"user\", \"content\": user_prompt}\n",
    "        ]\n",
    "        response = ollama.chat(model=MODEL, messages=messages)\n",
    "        return response['message']['content']\n",
    "    except Exception as e:\n",
    "        return f\"Error communicating with Ollama: {e}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "60e98b28-06d9-4303-b8ca-f7b798244eb4",
   "metadata": {},
   "outputs": [],
   "source": [
    "system_prompt = \"\"\"\n",
    "You are a helpful real estate assistant specializing in UK property rentals. Your job is to guide users in finding houses to rent, especially in Durham. Follow these rules:\n",
    "1. Always ask clarifying questions if user input is vague. Determine location, budget, number of bedrooms, and tenant type (e.g. student, family, professional).\n",
    "2. Use structured data provided from the website (like property listings) to identify relevant options.\n",
    "3. If listings are provided, filter and rank them based on the user's preferences.\n",
    "4. Recommend up to 5 top properties with rent price, bedroom count, key features, and location.\n",
    "5. Always respond in markdown with clean formatting using headers, bold text, and bullet points.\n",
    "6. If no listings match well, provide tips (e.g. \"try adjusting your budget or search radius\").\n",
    "7. Stay concise, helpful, and adapt to whether the user is a student, family, couple, or solo tenant.\n",
    "\"\"\"\n",
    "\n",
    "def user_prompt_for_renting(website, user_needs):\n",
    "    return f\"\"\"\n",
    "I want to rent a house and here's what I'm looking for:\n",
    "{user_needs}\n",
    "\n",
    "Here are the property listings I found on the website titled: \"{website.title}\".\n",
    "\n",
    "Please analyze them and recommend the best 3–5 options that match my needs. If none are suitable, tell me why and offer suggestions.\n",
    "\n",
    "The page content is below:\n",
    "{website.text[:4000]}\n",
    "\"\"\"  # content is truncated for token limits"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef420f4b-e3d2-4fbd-bf6f-811f2c8536e0",
   "metadata": {},
   "source": [
    "## Ollama Package"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cf128af-4ece-41ab-b353-5c8564c7de1d",
   "metadata": {},
   "outputs": [],
   "source": [
    "if __name__ == \"__main__\":  \n",
    "    print(\"Starting AI Property Rental Assistant...\")\n",
    "    print(\"=\" * 50)\n",
    "    \n",
    "    website_url = \"https://www.onthemarket.com/to-rent/property/durham/\"\n",
    "    print(f\"🔍 Scraping properties from: {website_url}\")\n",
    "    \n",
    "    website = Website(website_url)\n",
    "    print(f\"Website Title: {website.title}\")\n",
    "    print(f\"Content Length: {len(website.text)} characters\")\n",
    "    print(f\"Successfully scraped property listings\\n\")\n",
    "    \n",
    "    user_needs = \"I'm a student looking for a 2-bedroom house in Durham under £2,000/month\"\n",
    "    print(f\"User Requirements: {user_needs}\\n\")\n",
    "    \n",
    "    user_prompt = user_prompt_for_renting(website, user_needs)\n",
    "    print(\"Generating AI recommendations...\")\n",
    "    \n",
    "    # Choose which method to use (comment out the one you don't want)\n",
    "    \n",
    "    # Method 1: Using ollama Python library\n",
    "    output = house_renting_ollama(system_prompt, user_prompt)\n",
    "    \n",
    "    # Method 2: Using direct API call\n",
    "    # output = house_renting(system_prompt, user_prompt)\n",
    "    \n",
    "    display(Markdown(output))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:llms]",
   "language": "python",
   "name": "conda-env-llms-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
